package service

import (
	v1 "blog/api/v1"
	"blog/internal/model"
	"blog/internal/repository"
	"context"
	"errors"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
	"time"
)

type UserService interface {
	Login(ctx context.Context, username string, password string) (*model.User, string, error)
	GetAllUsers(ctx context.Context) ([]*model.User, error)
	ResetPassword(ctx context.Context, userId uint) error
	DeleteUser(ctx context.Context, userId uint) error
	UpdateUserInfo(ctx context.Context, req *v1.UpdateUserReq) error
	Register(ctx context.Context, req *v1.RegisterUserReq) (*model.User, error)
	UpgradeUserTypeToCreator(ctx context.Context, userId uint) error
}

func NewUserService(
	service *Service,
	userRepo repository.UserRepository,
) UserService {
	return &userService{
		userRepo: userRepo,
		Service:  service,
	}
}

type userService struct {
	userRepo repository.UserRepository
	*Service
}

// Login 用户登录逻辑
func (s *userService) Login(ctx context.Context, username string, password string) (*model.User, string, error) {

	foundUser, err := s.userRepo.GetByUsername(ctx, username)
	if err != nil {
		return nil, "", err
	}
	if foundUser == nil {
		return nil, "", errors.New("用户不存在")
	}
	if foundUser.Type == model.UserTypeBanned {
		return nil, "", errors.New("用户身份待审核")
	}
	// 校验密码
	if err := bcrypt.CompareHashAndPassword([]byte(foundUser.Password), []byte(password)); err != nil {
		return nil, "", errors.New("密码错误")
	}
	// ✔ 签发 JWT token
	expiresAt := time.Now().Add(24 * time.Hour) // 有效期可配置
	token, err := s.jwt.GenToken(foundUser.ID, foundUser.Type, expiresAt)
	if err != nil {
		return nil, "", errors.New("token生成失败")
	}

	return foundUser, token, nil
}
func (s *userService) GetAllUsers(ctx context.Context) ([]*model.User, error) {
	return s.userRepo.List(ctx) // 假设已有 List 方法
}

func (s *userService) ResetPassword(ctx context.Context, userId uint) error {
	// 查询用户是否存在
	user, err := s.userRepo.GetByID(ctx, userId)
	if err != nil {
		return err
	}
	if user == nil {
		return errors.New("用户不存在")
	}

	// 生成新密码 hash
	hashedPwd, err := bcrypt.GenerateFromPassword([]byte("123456"), bcrypt.DefaultCost)
	if err != nil {
		return err
	}

	// 更新密码字段
	user.Password = string(hashedPwd)
	return s.userRepo.Update(ctx, user) // 假设这是你的通用更新方法
}

func (s *userService) DeleteUser(ctx context.Context, userId uint) error {
	return s.userRepo.DeleteByID(ctx, userId)
}

func (s *userService) UpdateUserInfo(ctx context.Context, req *v1.UpdateUserReq) error {
	user, err := s.userRepo.GetByID(ctx, req.UserId)
	if err != nil {
		return err
	}
	if req.UserName != "" {
		user.UserName = req.UserName
	}
	if req.NewPassword != "" {
		if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.OldPassword)); err != nil {
			return errors.New("密码错误")
		}
		hashedPwd, err := bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost)
		if err != nil {
			return err
		}
		user.Password = string(hashedPwd)
	}
	//todo:头像更新待增加
	return s.userRepo.Update(ctx, user)
}

func (s *userService) Register(ctx context.Context, req *v1.RegisterUserReq) (*model.User, error) {
	existUser, err := s.userRepo.GetByUsername(ctx, req.UserName)
	if !errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, err
	}
	if existUser != nil {
		return nil, errors.New("用户名已存在")
	}

	hashedPwd, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
	if err != nil {
		return nil, err
	}

	newUser := &model.User{
		UserName: req.UserName,
		Password: string(hashedPwd),
		Type:     3, // 默认普通用户
	}

	if err := s.userRepo.Create(ctx, newUser); err != nil {
		return nil, err
	}

	return newUser, nil
}

func (s *userService) UpgradeUserTypeToCreator(ctx context.Context, userId uint) error {
	user, err := s.userRepo.GetByID(ctx, userId)
	if err != nil {
		return err
	}
	if user == nil {
		return errors.New("用户不存在")
	}
	if user.Type == 2 {
		return errors.New("用户已是创作者")
	}
	return s.userRepo.UpdateUserType(ctx, userId)
}
